package com.excesys.exsecs.energy.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.excesys.exsecs.energy.dto.BamSSubareaDTO;
import com.excesys.exsecs.energy.entity.*;
import com.excesys.exsecs.energy.mapper.DimAreaMapper;
import com.excesys.exsecs.energy.mapper.RegDevMapper;
import com.excesys.exsecs.energy.service.*;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Year;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 能耗维度：区域
 *
 * @author lxc
 * @date 2024-02-26 14:13:06
 */
@Service
@RequiredArgsConstructor
public class DimAreaServiceImpl extends ServiceImpl<DimAreaMapper, DimArea> implements DimAreaService {

    private final DevAreaMapService devAreaMapService;
    private final SubareaAreaMapService subareaAreaMapService;
    private final RegDevMapper regDevMapper;

    private final PowerHourFlowService powerHourFlowService;

    private final WaterHourFlowService waterHourFlowService;

    @Override
    public List<Tree<Long>> queryTree(DimArea dimArea) {
        List<DimArea> areaList = this.list(Wrappers.<DimArea>lambdaQuery().eq(DimArea::getEnergyType, dimArea.getEnergyType()).like(StringUtils.isNotBlank(dimArea.getAreaName()), DimArea::getAreaName, dimArea.getAreaName()));
        if (CollectionUtils.isNotEmpty(areaList)) {
            List<Long> areaIds = areaList.stream().map(DimArea::getId).collect(Collectors.toList());
            List<DevAreaMap> devAreaMaps = devAreaMapService.list(Wrappers.<DevAreaMap>lambdaQuery().in(DevAreaMap::getAreaId, areaIds));
            if (CollectionUtils.isNotEmpty(devAreaMaps)) {
                Map<Long, List<DevAreaMap>> maps = devAreaMaps.stream().collect(Collectors.groupingBy(DevAreaMap::getAreaId));
                List<String> unitNos = devAreaMaps.stream().map(DevAreaMap::getUnitNo).distinct().collect(Collectors.toList());
                List<RegDev> regDevs = regDevMapper.selectList(Wrappers.<RegDev>lambdaQuery().in(RegDev::getUnitNo, unitNos));
                maps.forEach((key, value) -> {
                    value.forEach(it -> {
                        String unitNo = it.getUnitNo();
                        RegDev regDev = regDevs.stream().filter(f -> f.getUnitNo().equals(unitNo)).findFirst().orElse(null);
                        if (ObjectUtils.isNotEmpty(regDev)) {
                            it.setUnitName(regDev.getUnitName());
                            it.setDeviceNo(regDev.getDeviceNo());
                            it.setDeviceName(regDev.getDeviceName());
                            it.setEnergyType(regDev.getEnergyType());
                        }
                    });
                });
                for (DimArea area : areaList) {
                    List<DevAreaMap> devAreaMaps2 = maps.get(area.getId());
                    if (CollectionUtils.isNotEmpty(devAreaMaps2)) {
                        area.setDevAreaMapList(devAreaMaps2);
                        List<String> collect = devAreaMaps2.stream().map(DevAreaMap::getUnitName).collect(Collectors.toList());
                        area.setDevAreaNameStr(String.join(",", collect));
                    }
                }
            }
        }
        List<TreeNode<Long>> collect = areaList.stream().map(getNodeFunction()).collect(Collectors.toList());
        return TreeUtil.build(collect, 0L);
    }

    @Override
    public DimArea getAreaById(Long id) {
        DimArea area = this.getById(id);
        if (ObjectUtils.isNotEmpty(area)) {
            List<DevAreaMap> devAreaMaps = devAreaMapService.list(Wrappers.<DevAreaMap>lambdaQuery().eq(DevAreaMap::getAreaId, area.getId()));
            if (CollectionUtils.isNotEmpty(devAreaMaps)) {
                devAreaMaps.forEach(dev -> {
                    List<RegDev> regDevs = regDevMapper.selectList(Wrappers.<RegDev>lambdaQuery().eq(RegDev::getUnitNo, dev.getUnitNo()));
                    if (CollectionUtils.isNotEmpty(regDevs)) {
                        RegDev regDev = regDevs.get(0);
                        dev.setUnitName(regDev.getUnitName());
                        dev.setDeviceNo(regDev.getDeviceNo());
                        dev.setDeviceName(regDev.getDeviceName());
                        dev.setEnergyType(regDev.getEnergyType());
                    }
                });
                area.setDevAreaMapList(devAreaMaps);
            }
            List<SubareaAreaMap> list = subareaAreaMapService.list(Wrappers.<SubareaAreaMap>lambdaQuery().eq(SubareaAreaMap::getAreaId, area.getId()));
            if (CollectionUtils.isNotEmpty(list)) {
                list.forEach(areaMap -> {
                    BamSSubareaDTO bamSSubareaDTO = regDevMapper.queryBamSSubareaDTO(areaMap.getSubareaCode());
                    if (ObjectUtils.isNotEmpty(bamSSubareaDTO)) {
                        areaMap.setSubareaCn(bamSSubareaDTO.getSubareaCn());
                        areaMap.setSubareaArea(bamSSubareaDTO.getSubareaArea());
                    }
                });
            }
        }
        return area;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveDevAreaMap(DimArea dimArea) {
        if (CollectionUtils.isNotEmpty(dimArea.getDevAreaMapList())) {
            //删除操作：
            List<DevAreaMap> dbDataList = devAreaMapService.list(Wrappers.<DevAreaMap>lambdaQuery().eq(DevAreaMap::getAreaId, dimArea.getId()));
            List<DevAreaMap> paramList = dimArea.getDevAreaMapList();
            List<DevAreaMap> resultList = dbDataList.stream()
                    .filter(db -> paramList.stream().filter(item -> item.getId() != null).noneMatch(param -> param.getId().equals(db.getId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(resultList)) {
                List<Long> ids = resultList.stream().map(DevAreaMap::getAreaId).collect(Collectors.toList());
                List<String> unitNos = resultList.stream().map(DevAreaMap::getUnitNo).collect(Collectors.toList());
                //递归后存放的区域id集合
                List<Long> areaIds = new ArrayList<>();
                areaIds.addAll(ids);
                areaIds = recursiveSelect(ids, areaIds);
                devAreaMapService.remove(Wrappers.<DevAreaMap>lambdaQuery().in(DevAreaMap::getAreaId, areaIds).in(DevAreaMap::getUnitNo, unitNos));
            }
            paramList.forEach(item -> {
                item.setAreaId(dimArea.getId());
                List<RegDev> regDevs = regDevMapper.selectList(Wrappers.<RegDev>lambdaQuery().eq(RegDev::getUnitNo, item.getUnitNo()));
                if (CollectionUtils.isNotEmpty(regDevs)) {
                    RegDev regDev = regDevs.get(0);
                    item.setRegDevId(regDev.getId());
                    item.setEnergyType(regDev.getEnergyType());
                    List<DevAreaMap> list = devAreaMapService.list(Wrappers.<DevAreaMap>lambdaQuery().eq(DevAreaMap::getAreaId, dimArea.getId()).eq(DevAreaMap::getUnitNo, item.getUnitNo()));
                    if (list.size() > 0) {
                        devAreaMapService.updateById(item);
                    } else {
                        item.setId(null);
                        devAreaMapService.save(item);
                    }
                }
            });
        } else {
            List<Long> ids = new ArrayList<>();
            List<Long> areaIds = new ArrayList<>();
            ids.add(dimArea.getId());
            areaIds.add(dimArea.getId());
            areaIds = recursiveSelect(ids, areaIds);
            devAreaMapService.remove(Wrappers.<DevAreaMap>lambdaQuery().in(DevAreaMap::getAreaId, areaIds));
        }
        return this.lambdaUpdate().set(DimArea::getIsother, dimArea.getIsother()).eq(DimArea::getId, dimArea.getId()).update(new DimArea());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeAreaBatchByIds(List<Long> ids) {
        recursiveDelete(ids);
        return true;
    }

    @Override
    public List<DevAreaMap> getMetersById(DimArea dimArea) {
        if (dimArea.getParentId() != 0) {
            DimArea area = this.getOne(Wrappers.<DimArea>lambdaQuery().eq(DimArea::getId, dimArea.getParentId()));
            if (ObjectUtils.isNotEmpty(area)) {
                List<DevAreaMap> list = devAreaMapService.list(Wrappers.<DevAreaMap>lambdaQuery().eq(DevAreaMap::getAreaId, area.getId()));
                if (CollectionUtils.isNotEmpty(list)) {
                    list.forEach(item -> {
                        RegDev regDev = regDevMapper.selectOne(Wrappers.<RegDev>lambdaQuery().eq(RegDev::getUnitNo, item.getUnitNo()));
                        if (ObjectUtils.isNotEmpty(regDev)) {
                            item.setUnitName(regDev.getUnitName());
                        }
                    });
                    return list;
                }
            }
        }
        List<RegDev> regDevs = regDevMapper.selectList(Wrappers.<RegDev>lambdaQuery().eq(RegDev::getEnergyType, dimArea.getEnergyType()));
        List<DevAreaMap> result = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(regDevs)) {
            regDevs.forEach(item -> {
                DevAreaMap dev = new DevAreaMap();
                dev.setUnitNo(item.getUnitNo());
                dev.setUnitName(item.getUnitName());
                result.add(dev);
            });
        }
        return result;
    }

    @NotNull
    private Function<DimArea, TreeNode<Long>> getNodeFunction() {
        return AreaCloumn -> {
            TreeNode<Long> node = new TreeNode<>();
            node.setId(AreaCloumn.getId());
            node.setName(AreaCloumn.getAreaName());
            node.setParentId(AreaCloumn.getParentId());
            // 扩展属性
            Map<String, Object> extra = new HashMap<>();
            extra.put("areaName", AreaCloumn.getAreaName());
            extra.put("isother", AreaCloumn.getIsother());
            extra.put("devAreaMapList", AreaCloumn.getDevAreaMapList());
            extra.put("devAreaNameStr", AreaCloumn.getDevAreaNameStr());
            node.setExtra(extra);
            return node;
        };
    }

    /**
     * 递归查询,返回区域id集合
     */
    private List<Long> recursiveSelect(List<Long> ids, List<Long> areaIds) {
        List<DimArea> dimAreas = this.listByIds(ids);
        if (CollectionUtils.isNotEmpty(dimAreas)) {
            List<DimArea> list = this.list(Wrappers.<DimArea>lambdaQuery().in(DimArea::getParentId, ids));
            List<Long> chlidIds = list.stream().map(DimArea::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(chlidIds)) {
                areaIds.addAll(chlidIds);
                recursiveSelect(chlidIds, areaIds);
            }
        }
        return areaIds;
    }

    /**
     * 递归删除
     */
    private void recursiveDelete(List<Long> ids) {
        List<DimArea> dimArea = this.listByIds(ids);
        if (CollectionUtils.isNotEmpty(dimArea)) {
            devAreaMapService.remove(Wrappers.<DevAreaMap>lambdaQuery().in(DevAreaMap::getAreaId, ids));
            this.removeBatchByIds(ids);
            List<DimArea> list = this.list(Wrappers.<DimArea>lambdaQuery().in(DimArea::getParentId, ids));
            List<Long> chlidIds = list.stream().map(DimArea::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(chlidIds)) {
                recursiveDelete(chlidIds);
            }
        }
    }


    @Override
    public JSONObject powerAreaSanchitou(String id, String startDate, String endDate) {
        List<String> idsList = new ArrayList();//递归后存放的区域id集合
        List<Map<String, Object>> listData = new ArrayList();//递归后存放的区域名称集合
        List<Map<String, Object>> tableData = new ArrayList();//递归后存放的区域名称与区域id
        DimArea areaOne = this.getOne(Wrappers.<DimArea>lambdaQuery().eq(DimArea::getId, id));//区域id
        Map<String, Object> map = new HashMap<>();//区域名称
        List<DimArea> areaList = new ArrayList();//用来接收所有的区域信息
        if (areaOne != null) {
            map.put("name", areaOne.getAreaName());//区域名称
            idsList.add(areaOne.getId().toString());//递归后存放的区域id集合
            listData.add(map);//递归后存放的区域名称集合
            map = new HashMap<>();//区域名称
            map.put("areaName", areaOne.getAreaName());
            map.put("areaId", areaOne.getId().toString());
            map.put("parentId", areaOne.getParentId());
            tableData.add(map);
            areaList = this.getBaseMapper().selectList(Wrappers.<DimArea>lambdaQuery());
        }
        recursionSanchitou(tableData, areaList, idsList, areaOne);//递归查询
        // 区域桑基图 - 使用LinkedHashSet去除重复 name 不然会报错
        //天,月,年 区域桑基图 时间数据的拼装
        List<Map<String, Object>> resultData = sankeyTimeData(idsList, startDate, endDate);
        JSONObject jsonPower = recursionData(tableData, resultData, areaList, listData);
        /*表格*/
        List<Map<String, Object>> table = new ArrayList();//递归后存放的区域名称与区域id
        tableData.forEach(model -> {
            // 查找对应的dayData
            Optional<Map<String, Object>> dayDataOpt = resultData.stream()
                    .filter(i -> i.get("areaId").toString().equals(model.get("areaId").toString())) // 假设DimArea有getId()方法
                    .findFirst();
            // 使用ifPresent来处理值（如果只需要在值存在时执行某些操作）
            dayDataOpt.ifPresent(dayData -> {
                // 在这里处理dayData
                if (!dayData.get("incrValue").toString().equals("0.0")) {
                    Map<String, Object> mapdata = new HashMap<>();
                    mapdata.put("areaName", model.get("areaName"));
                    // 根据dayData设置value
                    mapdata.put("value", dayData.get("incrValue"));
                    table.add(mapdata);
                }
            });
        });
        jsonPower.put("tableData", table);//表格
        return jsonPower;
    }

    @Override
    public JSONObject powerAreaBingtu(String startDate, String endDate) {
        JSONObject result = new JSONObject();
        //日期时间字符串转换
        DateTimeFormatter isoFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //获取数据库最新的时间格式 开始时间 与 结束时间
        Map newestTime = getNewestTime(startDate, endDate);
        //当日时间与当月时间
        String startTime = null;//起始时间
        String endTime = null;//结束时间
        LocalDateTime startDateTime = null;
        LocalDateTime endDateTime = null;
        if (!newestTime.isEmpty()) {
            startDateTime = LocalDateTime.parse(newestTime.get("startTime").toString(), isoFormatter);
            startTime = startDateTime.format(customFormatter);
            endDateTime = LocalDateTime.parse(newestTime.get("endTime").toString(), isoFormatter);
            endTime = endDateTime.format(customFormatter);
        }
        //环比时间
        String YoYStartTime = null;
        String YoYendTime = null;
        //日
        if (startDate.matches("\\d{4}-\\d{2}-\\d{2}") && endDate.matches("\\d{4}-\\d{2}-\\d{2}")) {
            //获取左天的时间用来做判断用
            LocalDate today = LocalDate.now();
            // 判断开始时间和结束时间是否都在今天
            if (!startDate.equals(today.toString()) && !endDate.equals(today.toString())) {
                if (startDate.equals(endDate)) {
                    LocalDate days = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")).plusDays(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(days.toString(), days.toString());
                    if (!newest.isEmpty()) {
                        LocalDateTime nextDayDateTime = startDateTime.plusDays(1);
                        // 格式化并打印明天的日期时间
                        LocalDateTime dateTime1 = LocalDateTime.parse(nextDayDateTime.toString(), isoFormatter);
                        endTime = dateTime1.format(customFormatter);
                    }
                } else {
                    //区间查询，根据结束时间，获取明天的00:00:00点
                    endTime = LocalDateTime.parse(endTime, customFormatter).toLocalDate().plusDays(1).atStartOfDay().format(customFormatter);
                }
            } else {
            }
        }
        //月
        if (startDate.matches("^\\d{4}-(0[1-9]|1[0-2])$") && endDate.matches("^\\d{4}-(0[1-9]|1[0-2])$")) {
            //1.获取当前月
            YearMonth currentMonth = YearMonth.from(LocalDate.now());
            if (!startDate.equals(currentMonth.toString()) && !endDate.equals(currentMonth.toString())) {
                if (startDate.equals(endDate)) {
                    YearMonth month = YearMonth.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM")).plusMonths(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(month.toString(), month.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                } else {
                    //区间查询，根据结束时间，获取明天的00:00:00点
                    YearMonth month = YearMonth.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM")).plusMonths(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(month.toString(), month.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                }
            } else {
            }
        }
        //年
        if (startDate.matches("^\\d{4}$") && endDate.matches("^\\d{4}$")) {
            //1.获取当前年
            Year month = Year.from(LocalDate.now());
            if (!startDate.equals(month.toString()) && !endDate.equals(month.toString())) {
                if (startDate.equals(endDate)) {
                    Year year = Year.parse(startDate, DateTimeFormatter.ofPattern("yyyy")).plusYears(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(year.toString(), year.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                } else {
                    //区间查询，根据结束时间，获取明年的00:00:00点
                    Year year = Year.parse(endDate, DateTimeFormatter.ofPattern("yyyy")).plusYears(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(year.toString(), year.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                }
            } else {
            }
        }
        AtomicReference<List<DimArea>> areaList = new AtomicReference<>(new ArrayList<>());
        List<String> idsList = new ArrayList<>();//递归后存放的分项id集合
        List<DimArea> DimAreas = this.getBaseMapper().selectList(Wrappers.<DimArea>lambdaQuery().eq(DimArea::getParentId, 0));
        if (!DimAreas.isEmpty()) {
            DimAreas.forEach(item -> {
                List<DimArea> dimList = this.getBaseMapper().selectList(Wrappers.<DimArea>lambdaQuery().eq(DimArea::getParentId, item.getId()));
                dimList.forEach(item1 -> {
                    areaList.get().add(item1);
                    idsList.add(String.valueOf(item1.getId()));
                });
            });
        }
        //查出来的数据
        List<Map<String, Object>> areaLinks = devAreaMapService.powerAreaLinks(startTime, endTime, idsList);
        // 取前五个元素
        List<Map<String, Object>> areaLinksFive = areaLinks.subList(0, Math.min(areaLinks.size(), 5));
        List<Map<String, Object>> resultData = new ArrayList();
        areaLinksFive.forEach(item -> {
            Map map = new HashMap<>();
            map.put("value", new BigDecimal(String.valueOf(item.get("incrValue"))).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
            Optional<DimArea> optionalarea = areaList.get().stream()
                    .filter(f -> f.getId().equals(item.get("areaId")))
                    .findFirst(); // 使用 findFirst 获取第一个匹配的元素
            DimArea area = optionalarea.orElse(null); // 如果找不到，则返回 null
            if (area != null) {
                System.out.println(area);
                map.put("name", area.getAreaName());
            }
            resultData.add(map);
        });
        if (areaLinks.size() > 5) {
            Map map = new HashMap<>();
            // 剩下的元素集合在一起
            List<Map<String, Object>> remaining = areaLinks.subList(5, areaLinks.size());
            map.put("name", "其他");
            Double totalCount = remaining.stream()
                    .mapToDouble(m -> {
                        if (m.containsKey("incrValue")) {
                            return (Double) m.get("incrValue");
                        } else {
                            return 0;
                        }
                    }).sum();
            map.put("value", totalCount);
            resultData.add(map);
        }
        result.put("data", resultData);
        return result;
    }


    //天,月,年 区域桑基图 时间数据的拼装
    private List<Map<String, Object>> sankeyTimeData(List<String> idsList, String startDate, String endDate) {
        List<Map<String, Object>> resultData = new ArrayList();
        //日期时间字符串转换
        DateTimeFormatter isoFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //获取数据库最新的时间格式 开始时间 与 结束时间
        Map newestTime = getNewestTime(startDate, endDate);
        //当日时间与当月时间
        String startTime = null;//起始时间
        String endTime = null;//结束时间
        LocalDateTime startDateTime = null;
        LocalDateTime endDateTime = null;
        if (!newestTime.isEmpty()) {
            startDateTime = LocalDateTime.parse(newestTime.get("startTime").toString(), isoFormatter);
            startTime = startDateTime.format(customFormatter);
            endDateTime = LocalDateTime.parse(newestTime.get("endTime").toString(), isoFormatter);
            endTime = endDateTime.format(customFormatter);
        }
        //日
        if (startDate.matches("\\d{4}-\\d{2}-\\d{2}") && endDate.matches("\\d{4}-\\d{2}-\\d{2}")) {
            //获取左天的时间用来做判断用
            LocalDate today = LocalDate.now();
            // 判断开始时间和结束时间是否都在今天
            if (!startDate.equals(today.toString()) && !endDate.equals(today.toString())) {
                if (startDate.equals(endDate)) {
                    LocalDate days = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")).plusDays(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(days.toString(), days.toString());
                    if (!newest.isEmpty()) {
                        LocalDateTime nextDayDateTime = startDateTime.plusDays(1);
                        // 格式化并打印明天的日期时间
                        LocalDateTime dateTime1 = LocalDateTime.parse(nextDayDateTime.toString(), isoFormatter);
                        endTime = dateTime1.format(customFormatter);
                    }
                } else {
                    //区间查询，根据结束时间，获取明天的00:00:00点
                    endTime = LocalDateTime.parse(endTime, customFormatter).toLocalDate().plusDays(1).atStartOfDay().format(customFormatter);
                }
            }
        }
        //月
        if (startDate.matches("^\\d{4}-(0[1-9]|1[0-2])$") && endDate.matches("^\\d{4}-(0[1-9]|1[0-2])$")) {
            //1.获取当前月
            YearMonth currentMonth = YearMonth.from(LocalDate.now());
            if (!startDate.equals(currentMonth.toString()) && !endDate.equals(currentMonth.toString())) {
                if (startDate.equals(endDate)) {
                    YearMonth month = YearMonth.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM")).plusMonths(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(month.toString(), month.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                } else {
                    //区间查询，根据结束时间，获取明天的00:00:00点
                    YearMonth month = YearMonth.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM")).plusMonths(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(month.toString(), month.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                }
            }
        }
        //年
        if (startDate.matches("^\\d{4}$") && endDate.matches("^\\d{4}$")) {
            //1.获取当前年
            Year month = Year.from(LocalDate.now());
            if (!startDate.equals(month.toString()) && !endDate.equals(month.toString())) {
                if (startDate.equals(endDate)) {
                    Year year = Year.parse(startDate, DateTimeFormatter.ofPattern("yyyy")).plusYears(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(year.toString(), year.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                } else {
                    //区间查询，根据结束时间，获取明年的00:00:00点
                    Year year = Year.parse(endDate, DateTimeFormatter.ofPattern("yyyy")).plusYears(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(year.toString(), year.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                }
            }
        }
        //区域能耗统计
        return devAreaMapService.powerAreaLinks(startTime, endTime, idsList);
    }


    /*
     * 区域桑基图-递归查询
     * */
    private List<Map<String, Object>> recursionSanchitou(List<Map<String, Object>> tableData, List<DimArea> areaList,
                                                         List idsList, DimArea areaOne) {
        if (ObjectUtils.isNotEmpty(areaOne)) {
            areaList.stream().forEach(dimArea -> {
                // 在这里处理每一个dimArea对象
                if (areaOne.getId().equals(dimArea.getParentId())) {
                    idsList.add(dimArea.getId().toString());
                    Map<String, Object> maptable = new HashMap<>();
                    maptable.put("areaName", dimArea.getAreaName());
                    maptable.put("areaId", dimArea.getId().toString());
                    maptable.put("parentId", dimArea.getParentId());
                    tableData.add(maptable);
                    recursionSanchitou(tableData, areaList, idsList, dimArea);
                }
            });
        }
        return null;
    }

    /*
     * listLinks 用来接收数据用的
     * tableData 区域数据接受名称
     * resultData 区域能耗统计数据
     * areaList 全部数据
     * */
    private JSONObject recursionData(List<Map<String, Object>> tableData, List<Map<String, Object>> resultData,
                                     List<DimArea> areaList, List<Map<String, Object>> listData) {
        List<Map<String, Object>> listLinks = new ArrayList<>();
        JSONObject jsonPower = new JSONObject();
        // 根据tableRow的areaId去areaList中查找父id为tableRow的parentId的数据
        List<Map<String, Object>> result = tableData.stream()
                .map(tableRow -> {
                    // 根据tableRow的areaId去areaList中查找父id为tableRow的parentId的数据
                    List<DimArea> parentArea = areaList.stream()
                            .filter(dimArea -> {
                                String areaId = tableRow.get("areaId").toString(); // 确保这里能安全转换为String
                                String parentId = dimArea.getParentId().toString(); // 确保这里能安全转换为String
                                return areaId.equals(parentId);
                            })
                            .collect(Collectors.toList());
                    // 如果找到了父区域数据，将其添加到tableRow中或进行其他处理
                    if (!parentArea.isEmpty()) {
                        parentArea.forEach(item -> {
                            // 查找对应的dayData
                            Optional<Map<String, Object>> dayDataOpt = resultData.stream()
                                    .filter(i -> i.get("areaId").equals(item.getId())) // 假设每个元素i都有get("areaId")方法
                                    .findFirst();
                            Map<String, Object> map = new HashMap<>();
                            Map<String, Object> map1 = new HashMap<>();
                            //使用ifPresent来处理值（如果只需要在值存在时执行某些操作）
                            dayDataOpt.ifPresent(dayData -> {
                                // 在这里处理dayData
                                if (!dayData.get("incrValue").toString().equals("0.0")) {
                                    map.put("source", tableRow.get("areaName").toString()); // 确保这里能安全转换为String
                                    map.put("target", item.getAreaName()); // 假设DimArea有getareaName()方法
                                    map.put("value", dayData.get("incrValue")); // 使用orElse提供一个默认值
                                    map1.put("name", item.getAreaName());
                                    // 将map添加到listLinks中（确保listLinks已定义）
                                    listLinks.add(map);
                                    // 将map添加到listData中（确保listData已定义）
                                    listData.add(map1);
                                }
                            });
                        });
                    }
                    // 不需要修改tableRow，直接返回
                    return tableRow;
                })
                .collect(Collectors.toList()); // 收集流的结果到result列表中
        // 区域桑基图 - 使用LinkedHashSet去除重复 name 不然会报错
        List<Map<String, Object>> uniqueData = listData.stream()
                .distinct() // 这不会工作，因为默认的distinct是基于整个对象的引用
                .collect(Collectors.toCollection(LinkedHashSet::new))
                .stream() // 转换回Stream以便可以进一步处理
                .collect(Collectors.toList()); // 收集回List
        jsonPower.put("data", uniqueData);//区域桑基图
        jsonPower.put("links", listLinks);
        return jsonPower;
    }

    /*
     * 能耗报表
     * */
    @Override
    public List<Map<String, Object>> getAreaReportPage(String ids, String date) {
        JSONObject backResult = new JSONObject();
        List<DimArea> areaList = new ArrayList<>();//区域数据
        List<String> idList = new ArrayList<>();//递归后存放的区域id集合
        //区域id 不等于空的时候
        if (StringUtils.isNotBlank(ids)) {
            String[] id = ids.split(",");
            idList = Arrays.asList(id);
            areaList = this.getBaseMapper().selectList(Wrappers.<DimArea>lambdaQuery().in(DimArea::getId, idList));
        } else {
            areaList = this.getBaseMapper().selectList(Wrappers.<DimArea>lambdaQuery());
            List<String> finalIdList = idList;
            areaList.forEach(item -> {
                finalIdList.add(item.getId().toString());
            });
        }
        String layerStartTime = null;
        String layerEndTime = null;
        List<Map<String, Object>> reportlist = new ArrayList<>();//报表数据
        String type = ""; //1日 2月 3年
        //日
        if (date.matches("\\d{4}-\\d{2}-\\d{2}")) {
            // Create图层时间
            layerStartTime = date + " 01";//开始时间
            // 解析给定的日期字符串
            LocalDate givenDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            // 获取明天的日期
            LocalDate nextDay = givenDate.plusDays(1);
            layerEndTime = nextDay.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 00";
            reportlist = devAreaMapService.dayReport(layerStartTime, layerEndTime, idList);
            type = "1";
        }
        //月
        if (date.matches("^\\d{4}-(0[1-9]|1[0-2])$")) {
            String BlurDate = date.replaceAll("-", "");
            reportlist = devAreaMapService.monthReport(BlurDate, idList);
            type = "2";
        }
        //年
        if (date.matches("^\\d{4}$")) {
            reportlist = devAreaMapService.yearReport(date, idList);
            type = "3";
        }
        return datReportMap(type, areaList, reportlist);
    }

    //报表数据组装
    public List<Map<String, Object>> datReportMap(String type, List<DimArea> areaList, List<Map<String, Object>> reportlist) {
        List<Map<String, Object>> reportList = new ArrayList<>();
        areaList.forEach(item -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("reportName", item.getAreaName());
                    AtomicReference<Double> totalSum = new AtomicReference<>(0.0);
                    reportlist.forEach(report -> {
                        if (report.get("areaId").toString().equals(item.getId().toString())) {
                            if (type.equals("1")) {
                                map.put("d_" + report.get("createTime").toString(), report.get("totalValue").toString());
                            }
                            if (type.equals("2")) {
                                map.put("m_" + report.get("createTime").toString(), report.get("totalValue").toString());
                            }
                            if (type.equals("3")) {
                                map.put("y_" + report.get("createTime").toString(), report.get("totalValue").toString());
                            }
                            totalSum.updateAndGet(v -> v + Double.valueOf(report.get("totalValue").toString()));
                        }
                    });
                    map.put("totalSum", new BigDecimal(String.valueOf(totalSum)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                    reportList.add(map);
                }
        );
        return reportList;
    }


    /*
     * 能耗对比
     * */
    @Override
    public JSONObject powerAreaContrast(String ids, String startDate, String endDate) {
        String[] id = ids.split(",");
        List<String> idList = Arrays.asList(id);
        List<DimArea> areaList = new ArrayList<>();
        if (StringUtils.isNotBlank(ids)) {
            areaList = this.getBaseMapper().selectList(Wrappers.<DimArea>lambdaQuery().in(DimArea::getId, idList));
        }
        String layerStartTime = null;
        String layerEndTime = null;
        List<Map<String, Object>> reportlist = new ArrayList<>();//报表数据
        String type = "0"; //1日 2月 3年 4其他
        //时
        if (startDate.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}$") && endDate.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}$")) {
            reportlist = devAreaMapService.dayReport(startDate, endDate, idList);
            List<Map<String, Object>> maplist = new ArrayList<>();//报表数据
            reportlist.forEach(r -> {
                Map<String, Object> map = new HashMap<>();
                map.put("totalValue", r.get("totalValue"));
                map.put("areaId", r.get("areaId"));
                LocalDateTime localDateTime = LocalDateTime.parse(r.get("timeValue").toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm"));
                map.put("createTime",localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                maplist.add(map);
            });
            reportlist = maplist;
            type = "4";
        }
        //日
        if (startDate.matches("\\d{4}-\\d{2}-\\d{2}") && endDate.matches("\\d{4}-\\d{2}-\\d{2}")) {
            //当天数据
            if (startDate.equals(endDate)) {
                //   Create图层时间
                layerStartTime = startDate + " 01";//开始时间
                // 解析给定的日期字符串
                LocalDate givenDate = LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                // 获取明天的日期
                LocalDate nextDay = givenDate.plusDays(1);
                layerEndTime = nextDay.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 00";
                reportlist = devAreaMapService.dayReport(layerStartTime, layerEndTime, idList);
                type = "1";
            } else {
                layerStartTime = startDate.replaceAll("-", "");
                layerEndTime = endDate.replaceAll("-", "");
                reportlist = devAreaMapService.daySectionReport(layerStartTime, layerEndTime, idList);
                type = "4";//其他
            }
        }
        //月
        if (startDate.matches("^\\d{4}-(0[1-9]|1[0-2])$") && endDate.matches("^\\d{4}-(0[1-9]|1[0-2])$")) {
            //前月数据
            if (startDate.equals(endDate)) {
                String BlurDate = startDate.replaceAll("-", "");
                reportlist = devAreaMapService.monthReport(BlurDate, idList);
                type = "2";
            } else {
                layerStartTime = startDate.replaceAll("-", "");
                layerEndTime = endDate.replaceAll("-", "");
                reportlist = devAreaMapService.monthSectionReport(layerStartTime, layerEndTime, idList);
                type = "4";
            }
        }
        // 年
        if (startDate.matches("^\\d{4}$") && endDate.matches("^\\d{4}$")) {
            if (startDate.equals(endDate)) {
                reportlist = devAreaMapService.yearReport(startDate, idList);
                type = "3";
            } else {
                //年的区间 开始时间
                Calendar calendar = Calendar.getInstance();
                calendar.set(Integer.parseInt(startDate), Calendar.JANUARY, 1); // 年份、月份（从0开始，1代表1月）、日期
                layerStartTime = new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(calendar.getTime());
                //年的区间 接受时间
                calendar.set(Integer.parseInt(endDate), Calendar.DECEMBER, 31); // 年份、月份（从0开始，1代表1月）、日期
                layerEndTime = new SimpleDateFormat("yyyy-MM-dd 23:00:00").format(calendar.getTime());
                reportlist = devAreaMapService.yearSectionReport(layerStartTime, layerEndTime, idList);
                type = "4";
            }
        }
        return layerContrast(type, areaList, reportlist);
    }

    //数据组装
    public JSONObject layerContrast(String type, List<DimArea> lists, List<Map<String, Object>> reportlist) {
        JSONObject result = new JSONObject();
        JSONObject resultPower = new JSONObject();
        List<Map<String, Object>> tableList = new ArrayList<>();
        List<String> legendData = new ArrayList<>();//递归后存放的名称
        List<String> xAxis = new ArrayList<>();
        //日
        if (type.equals("1")) {
            for (int h = 1; h < 25; h++) {
                String strHour = String.format("%02d", h);
                xAxis.add(strHour);
            }
        }
        //月
        if (type.equals("2")) {
            for (int day = 1; day <= 31; day++) {
                // 输出两位数的日期，如果是一位数则在前面补0
                String strDay = String.format("%02d", day);
                xAxis.add(strDay);
            }
        }
        //年
        if (type.equals("3")) {
            for (int m = 1; m < 13; m++) {
                String strMonth = String.format("%02d", m);
                xAxis.add(strMonth);
            }
        }
        //其他
        if (type.equals("4")) {
            List<String> finalXAxis = xAxis;
            reportlist.forEach(r -> {
                finalXAxis.add(r.get("createTime").toString());
            });
            xAxis = finalXAxis.stream()
                    .distinct() // 去重
                    .sorted() // 排序（自然顺序）
                    .collect(Collectors.toList());
        }
        List<Map<String, Object>> serieslist = new ArrayList<>();//图层拼装数据
        List<String> finalXAxis1 = xAxis;
        lists.forEach(item -> {
            Map<String, Object> map = new HashMap<>();
            legendData.add(item.getAreaName()); //图例名称
            map.put("name", item.getAreaName());//图例名称
            List<String> seriesData = new ArrayList<>();//图层数据
            Map<String, Object> tableMap = new HashMap<>();
            tableMap.put("reportName", item.getAreaName());//表格头部名称
            List<Map<String, Object>> yearData = reportlist.stream().filter(bo -> bo.get("areaId").equals(item.getId()))
                    .collect(Collectors.toList());
            AtomicReference<Double> sumTotal = new AtomicReference<>(0.0);
            finalXAxis1.stream().forEach(x -> {
                List<Map<String, Object>> data = yearData.stream().filter(y -> y.get("createTime").toString().equals(x.toString()))
                        .collect(Collectors.toList());
                Double powerData = null;
                if (!data.isEmpty()) {
                    if (type.equals("1")) {
                        powerData = Double.parseDouble(data.get(0).get("totalValue").toString());
                        tableMap.put("d_" + x, powerData);
                        seriesData.add(String.valueOf(powerData));//图层数据
                        Double finalPowerData = powerData;
                        sumTotal.updateAndGet(v -> v + finalPowerData);
                    }
                    if (type.equals("2")) {
                        powerData = Double.parseDouble(data.get(0).get("totalValue").toString());
                        tableMap.put("m_" + x, powerData);
                        seriesData.add(String.valueOf(powerData));//图层数据
                        Double finalPowerData = powerData;
                        sumTotal.updateAndGet(v -> v + finalPowerData);
                    }
                    if (type.equals("3")) {
                        powerData = Double.parseDouble(data.get(0).get("totalValue").toString());
                        tableMap.put("y_" + x, powerData);
                        seriesData.add(String.valueOf(powerData));//图层数据
                        Double finalPowerData = powerData;
                        sumTotal.updateAndGet(v -> v + finalPowerData);
                    }
                    if (type.equals("4")) {
                        powerData = Double.parseDouble(data.get(0).get("totalValue").toString());
                        tableMap.put("q_" + x, powerData);
                        seriesData.add(String.valueOf(powerData));//图层数据
                        Double finalPowerData = powerData;
                        sumTotal.updateAndGet(v -> v + finalPowerData);
                    }

                } else {
                    if (type.equals("1")) {
                        tableMap.put("d_" + x, "0.0");
                        seriesData.add("-");//图层数据
                    }
                    if (type.equals("2")) {
                        tableMap.put("m_" + x, "0.0");
                        seriesData.add("-");//图层数据
                    }
                    if (type.equals("3")) {
                        tableMap.put("y_" + x, "0.0");
                        seriesData.add("-");//图层数据
                    }
                    if (type.equals("4")) {
                        tableMap.put("q_" + x, "0.0");
                        seriesData.add("-");//图层数据
                    }
                }
            });
            tableMap.put("sumTotal", new BigDecimal(String.valueOf(sumTotal)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
            map.put("data", seriesData);//图层数据
            serieslist.add(map);//图层数据组装
            tableList.add(tableMap);//表格数据组装
        });
        resultPower.put("series", serieslist);
        resultPower.put("legendData", legendData);
        resultPower.put("xAxisData", xAxis);
        result.put("resultLayer", resultPower);//图层
        result.put("tableData", tableList);//表格
        return result;
    }

    //区域能耗排序
    @Override
    public List<Map<String, Object>> areaSort(String ids, String startDate, String endDate, String order, String energyType) {
        AtomicReference<List<DimArea>> areaList = new AtomicReference<>(new ArrayList<>());//区域数据
        List<String> idList;//递归后存放的区域id集合
        if (!ids.isEmpty()) {
            String[] id = ids.split(",");
            idList = Arrays.asList(id);
            List<DimArea> DimAreas = this.getBaseMapper().selectList(Wrappers.<DimArea>lambdaQuery().in(DimArea::getId, idList)
                    .eq(DimArea::getEnergyType, energyType));
            areaList.set(DimAreas);
        } else {
            idList = new ArrayList<>();
            //获取区域信息
            List<DimArea> DimAreas = this.getBaseMapper().selectList(Wrappers.<DimArea>lambdaQuery().eq(DimArea::getParentId, 0)
                    .eq(DimArea::getEnergyType, energyType));
            if (!DimAreas.isEmpty()) {
                DimAreas.forEach(item -> {
                    areaList.set(this.getBaseMapper().selectList(Wrappers.<DimArea>lambdaQuery().eq(DimArea::getParentId, item.getId())));
                    areaList.get().forEach(item1 -> {
                        idList.add(String.valueOf(item1.getId()));
                    });
                });
            }
        }
        //日期时间字符串转换
        DateTimeFormatter isoFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //获取数据库最新的时间格式 开始时间 与 结束时间
        Map newestTime = getNewestTime(startDate, endDate);
        //当日时间与当月时间
        String startTime = null;//起始时间
        String endTime = null;//结束时间
        //环比的时间
        LocalDateTime startDateTime = null;
        LocalDateTime endDateTime = null;
        if (!newestTime.isEmpty()) {
            startDateTime = LocalDateTime.parse(newestTime.get("startTime").toString(), isoFormatter);
            startTime = startDateTime.format(customFormatter);
            endDateTime = LocalDateTime.parse(newestTime.get("endTime").toString(), isoFormatter);
            endTime = endDateTime.format(customFormatter);
        }
        //时
        if (startDate.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}$") && endDate.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}$")) {
            startTime = startDate;
            endTime= endDate;
        }
        //日
        if (startDate.matches("\\d{4}-\\d{2}-\\d{2}") && endDate.matches("\\d{4}-\\d{2}-\\d{2}")) {
            //获取左天的时间用来做判断用
            LocalDate today = LocalDate.now();
            // 判断开始时间和结束时间是否都在今天
            if (!startDate.equals(today.toString()) && !endDate.equals(today.toString())) {
                if (startDate.equals(endDate)) {
                    LocalDate days = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")).plusDays(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(days.toString(), days.toString());
                    if (!newest.isEmpty()) {
                        LocalDateTime nextDayDateTime = startDateTime.plusDays(1);
                        // 格式化并打印明天的日期时间
                        LocalDateTime dateTime1 = LocalDateTime.parse(nextDayDateTime.toString(), isoFormatter);
                        endTime = dateTime1.format(customFormatter);
                    }
                } else {
                    //区间查询，根据结束时间，获取明天的00:00:00点
                    endTime = LocalDateTime.parse(endTime, customFormatter).toLocalDate().plusDays(1).atStartOfDay().format(customFormatter);
                }
            }
        }
        //月
        if (startDate.matches("^\\d{4}-(0[1-9]|1[0-2])$") && endDate.matches("^\\d{4}-(0[1-9]|1[0-2])$")) {
            //1.获取当前月
            YearMonth currentMonth = YearMonth.from(LocalDate.now());
            if (!startDate.equals(currentMonth.toString()) && !endDate.equals(currentMonth.toString())) {
                if (startDate.equals(endDate)) {
                    YearMonth month = YearMonth.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM")).plusMonths(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(month.toString(), month.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                } else {
                    //区间查询，根据结束时间，获取明天的00:00:00点
                    YearMonth month = YearMonth.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM")).plusMonths(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(month.toString(), month.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                }
            }
        }
        //年
        if (startDate.matches("^\\d{4}$") && endDate.matches("^\\d{4}$")) {
            //1.获取当前年
            Year month = Year.from(LocalDate.now());
            if (!startDate.equals(month.toString()) && !endDate.equals(month.toString())) {
                if (startDate.equals(endDate)) {
                    Year year = Year.parse(startDate, DateTimeFormatter.ofPattern("yyyy")).plusYears(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(year.toString(), year.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                } else {
                    //区间查询，根据结束时间，获取明年的00:00:00点
                    Year year = Year.parse(endDate, DateTimeFormatter.ofPattern("yyyy")).plusYears(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(year.toString(), year.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                }
            }
        }
        //区域能耗排序
        List<Map<String, Object>> resultData = new ArrayList<>();//排序数据
        if (startTime != null && endTime != null) {
            resultData = devAreaMapService.areaSortRank(startTime, endTime, idList, energyType);
        }
        return areaSortData(order, areaList, resultData);
    }

    //区域能耗排序-数据组装
    private List<Map<String, Object>> areaSortData(String order, AtomicReference<List<DimArea>> areaList, List<Map<String, Object>> resultData) {
        List<Map<String, Object>> tableData = new ArrayList<>();//表格数据>
        //区域数据累加总和 -计算百分比
        Double totalCount = resultData.stream()
                .mapToDouble(map -> {
                    if (map.containsKey("incrValue")) {
                        return (Double) map.get("incrValue");
                    } else {
                        return 0;
                    }
                }).sum();

        resultData.forEach(item -> {
            Map<String, Object> map = new HashMap<>();
            if (!item.get("incrValue").toString().equals("0.0") && !item.get("incrValue").toString().equals("0.0")) {
                Double percent = (Double.parseDouble(item.get("incrValue").toString()) / Double.parseDouble(totalCount.toString())) * 100; // 增长率
                map.put("percent", new BigDecimal(percent).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
            } else {
                map.put("percent", "0");
            }
            map.put("incrValue", new BigDecimal(String.valueOf(item.get("incrValue"))).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
            areaList.get().forEach(item1 -> {
                if (item1.getId().toString().equals(item.get("areaId").toString())) {
                    map.put("sortName", item1.getAreaName());
                    tableData.add(map);
                }
            });
        });
        return getMaps(order, tableData);
    }

    @org.jetbrains.annotations.NotNull
    private List<Map<String, Object>> getMaps(String order, List<Map<String, Object>> mapList2) {
        List<Map<String, Object>> waterData;
        if ("desc".equals(order)) {
            waterData = mapList2.stream().sorted((c1, c2) -> MapUtils.getDouble(c2, "incrValue").
                    compareTo(MapUtils.getDouble(c1, "incrValue"))).collect(Collectors.toList());
        } else {
            waterData = mapList2.stream().sorted(Comparator.comparing(mp -> (Double) mp.get("incrValue"))).
                    collect(Collectors.toList());
        }
        return waterData;
    }

    //区域能耗排序 - 水
    @Override
    public List<Map<String, Object>> areaSortWaterRank(String ids, String startDate, String endDate, String order, String energyType) {
        AtomicReference<List<DimArea>> areaList = new AtomicReference<>(new ArrayList<>());//区域数据
        List<String> idList;//递归后存放的区域id集合
        if (!ids.isEmpty()) {
            String[] id = ids.split(",");
            idList = Arrays.asList(id);
            List<DimArea> DimAreas = this.getBaseMapper().selectList(Wrappers.<DimArea>lambdaQuery().in(DimArea::getId, idList)
                    .eq(DimArea::getEnergyType, energyType));
            areaList.set(DimAreas);
        } else {
            idList = new ArrayList<>();
            //获取区域信息
            List<DimArea> DimAreas = this.getBaseMapper().selectList(Wrappers.<DimArea>lambdaQuery().eq(DimArea::getParentId, 0)
                    .eq(DimArea::getEnergyType, energyType));
            if (!DimAreas.isEmpty()) {
                DimAreas.forEach(item -> {
                    areaList.set(this.getBaseMapper().selectList(Wrappers.<DimArea>lambdaQuery().eq(DimArea::getParentId, item.getId())));
                    areaList.get().forEach(item1 -> {
                        idList.add(String.valueOf(item1.getId()));
                    });
                });
            }
        }
        //日期时间字符串转换
        DateTimeFormatter isoFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //获取数据库最新的时间格式 开始时间 与 结束时间
        Map newestTime = getNewestWaterTime(startDate, endDate);
        //当日时间与当月时间
        String startTime = null;//起始时间
        String endTime = null;//结束时间
        //环比的时间
        LocalDateTime startDateTime = null;
        LocalDateTime endDateTime = null;
        if (!newestTime.isEmpty()) {
            startDateTime = LocalDateTime.parse(newestTime.get("startTime").toString(), isoFormatter);
            startTime = startDateTime.format(customFormatter);
            endDateTime = LocalDateTime.parse(newestTime.get("endTime").toString(), isoFormatter);
            endTime = endDateTime.format(customFormatter);
        }
        //时
        if (startDate.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}$") && endDate.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}$")) {
            startTime = startDate;
            endTime= endDate;
        }
        //日
        if (startDate.matches("\\d{4}-\\d{2}-\\d{2}") && endDate.matches("\\d{4}-\\d{2}-\\d{2}")) {
            //获取左天的时间用来做判断用
            LocalDate today = LocalDate.now();
            // 判断开始时间和结束时间是否都在今天
            if (!startDate.equals(today.toString()) && !endDate.equals(today.toString())) {
                if (startDate.equals(endDate)) {
                    LocalDate days = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")).plusDays(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(days.toString(), days.toString());
                    if (!newest.isEmpty()) {
                        LocalDateTime nextDayDateTime = startDateTime.plusDays(1);
                        // 格式化并打印明天的日期时间
                        LocalDateTime dateTime1 = LocalDateTime.parse(nextDayDateTime.toString(), isoFormatter);
                        endTime = dateTime1.format(customFormatter);
                    }
                } else {
                    //区间查询，根据结束时间，获取明天的00:00:00点
                    endTime = LocalDateTime.parse(endTime, customFormatter).toLocalDate().plusDays(1).atStartOfDay().format(customFormatter);
                }
            }
        }
        //月
        if (startDate.matches("^\\d{4}-(0[1-9]|1[0-2])$") && endDate.matches("^\\d{4}-(0[1-9]|1[0-2])$")) {
            //1.获取当前月
            YearMonth currentMonth = YearMonth.from(LocalDate.now());
            if (!startDate.equals(currentMonth.toString()) && !endDate.equals(currentMonth.toString())) {
                if (startDate.equals(endDate)) {
                    YearMonth month = YearMonth.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM")).plusMonths(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(month.toString(), month.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                } else {
                    //区间查询，根据结束时间，获取明天的00:00:00点
                    YearMonth month = YearMonth.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM")).plusMonths(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(month.toString(), month.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                }
            }
        }
        //年
        if (startDate.matches("^\\d{4}$") && endDate.matches("^\\d{4}$")) {
            //1.获取当前年
            Year month = Year.from(LocalDate.now());
            if (!startDate.equals(month.toString()) && !endDate.equals(month.toString())) {
                if (startDate.equals(endDate)) {
                    Year year = Year.parse(startDate, DateTimeFormatter.ofPattern("yyyy")).plusYears(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(year.toString(), year.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                } else {
                    //区间查询，根据结束时间，获取明年的00:00:00点
                    Year year = Year.parse(endDate, DateTimeFormatter.ofPattern("yyyy")).plusYears(1);
                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
                    Map newest = getNewestTime(year.toString(), year.toString());
                    if (!newest.isEmpty()) {
                        // 格式化并打印明天的日期时间
                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
                    }
                }
            }
        }
        //区域能耗排序
        List<Map<String, Object>> resultData = new ArrayList<>();//排序数据
        if (startTime != null && endTime != null) {
            resultData = devAreaMapService.areaSortWaterRank(startTime, endTime, idList, energyType);
        }
        return areaSortData(order, areaList, resultData);
    }


    /*
     * 区域能耗排名
     * */
    @Override
    public JSONObject areaRanking(String ids, String date, String order) {
        String[] id = ids.split(",");
        List<String> idList = Arrays.asList(id);
        List<DimArea> areaList = new ArrayList<>();
        //日期时间字符串转换
        DateTimeFormatter isoFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //获取数据库最新的时间格式 开始时间 与 结束时间
        Map newestTime = getNewestTime(date, date);
        System.out.println(newestTime);
        //当日时间与当月时间
        String startTime = null;//起始时间
        String endTime = null;//结束时间
        LocalDateTime startDateTime = null;
        LocalDateTime endDateTime = null;
        if (!newestTime.isEmpty()) {
            startDateTime = LocalDateTime.parse(newestTime.get("startTime").toString(), isoFormatter);
            startTime = startDateTime.format(customFormatter);
            endDateTime = LocalDateTime.parse(newestTime.get("endTime").toString(), isoFormatter);
            endTime = endDateTime.format(customFormatter);
        }
        //日
        if (date.matches("\\d{4}-\\d{2}-\\d{2}")) {
            //获取左天的时间用来做判断用
            LocalDate today = LocalDate.now();
            // 判断开始时间和结束时间是否都在今天
//            if (!date.equals(today.toString())) {
//                if (startDate.equals(endDate)) {
//                    LocalDate days = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")).plusDays(1);
//                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
//                    Map newest = getNewestTimes(days.toString(), days.toString());
//                    if (!newest.isEmpty()) {
//                        LocalDateTime nextDayDateTime = startDateTime.plusDays(1);
//                        // 格式化并打印明天的日期时间
//                        LocalDateTime dateTime1 = LocalDateTime.parse(nextDayDateTime.toString(), isoFormatter);
//                        endTime = dateTime1.format(customFormatter);
//                    }
//                } else {
//                    //区间查询，根据结束时间，获取明天的00:00:00点
//                    endTime = LocalDateTime.parse(endTime, customFormatter).toLocalDate().plusDays(1).atStartOfDay().format(customFormatter);
//                }
//            }
        }
//        //月
//        if (date.matches("^\\d{4}-(0[1-9]|1[0-2])$")) {
//            //1.获取当前月
//            YearMonth currentMonth = YearMonth.from(LocalDate.now());
//            if (!startDate.equals(currentMonth.toString()) && !endDate.equals(currentMonth.toString())) {
//                if (startDate.equals(endDate)) {
//                    YearMonth month = YearMonth.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM")).plusMonths(1);
//                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
//                    Map newest = getNewestTimes(month.toString(), month.toString());
//                    if (!newest.isEmpty()) {
//                        // 格式化并打印明天的日期时间
//                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
//                    }
//                } else {
//                    //区间查询，根据结束时间，获取明天的00:00:00点
//                    YearMonth month = YearMonth.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM")).plusMonths(1);
//                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
//                    Map newest = getNewestTimes(month.toString(), month.toString());
//                    if (!newest.isEmpty()) {
//                        // 格式化并打印明天的日期时间
//                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
//                    }
//                }
//            }
//        }
//        //年
//        if (date.matches("^\\d{4}$")) {
//            //1.获取当前年
//            Year month = Year.from(LocalDate.now());
//            if (!startDate.equals(month.toString()) && !endDate.equals(month.toString())) {
//                if (startDate.equals(endDate)) {
//                    Year year = Year.parse(startDate, DateTimeFormatter.ofPattern("yyyy")).plusYears(1);
//                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
//                    Map newest = getNewestTimes(year.toString(), year.toString());
//                    if (!newest.isEmpty()) {
//                        // 格式化并打印明天的日期时间
//                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
//                    }
//                } else {
//                    //区间查询，根据结束时间，获取明年的00:00:00点
//                    Year year = Year.parse(endDate, DateTimeFormatter.ofPattern("yyyy")).plusYears(1);
//                    //获取开始时间与结束时间 用来做判断用 明天有没有数据, 没有数据则不进入
//                    Map newest = getNewestTimes(year.toString(), year.toString());
//                    if (!newest.isEmpty()) {
//                        // 格式化并打印明天的日期时间
//                        endTime = LocalDateTime.parse(newest.get("startTime").toString(), isoFormatter).format(customFormatter);
//                    }
//                }
//            }
//        }

        return null;
    }


    //获取数据库最新的时间格式 开始时间 与 结束时间
    public Map getNewestTime(String startDate, String endDate) {
        Map map = new HashMap();
        String startSubzone = null;
        String endSubzone = null;
        if (startDate.matches("\\d{4}-\\d{2}-\\d{2}") || startDate.matches("^\\d{4}-(0[1-9]|1[0-2])$")) {
            startSubzone = startDate.substring(0, 7).replace("-", "");
        }
        if (endDate.matches("\\d{4}-\\d{2}-\\d{2}") || endDate.matches("^\\d{4}-(0[1-9]|1[0-2])$")) {
            endSubzone = endDate.substring(0, 7).replace("-", "");
        }
        //获取当前时间
        PowerHourFlow startHourFlow = this.powerHourFlowService.getBaseMapper().selectOne(Wrappers.<PowerHourFlow>lambdaQuery()
                .like(PowerHourFlow::getTimeValue, startDate)
                .eq(StringUtils.isNotBlank(startSubzone), PowerHourFlow::getTimePartition, startSubzone)
                .orderByAsc(PowerHourFlow::getTimeValue).last("LIMIT 1"));
        //获取上一条数据
        PowerHourFlow endHourFlow = this.powerHourFlowService.getBaseMapper().selectOne(Wrappers.<PowerHourFlow>lambdaQuery()
                .like(PowerHourFlow::getTimeValue, endDate)
                .eq(StringUtils.isNotBlank(endSubzone), PowerHourFlow::getTimePartition, endSubzone)
                .orderByDesc(PowerHourFlow::getTimeValue).last("LIMIT 1"));
        if (ObjectUtils.isNotEmpty(startHourFlow) && ObjectUtils.isNotEmpty(endHourFlow)) {
            map.put("startTime", startHourFlow.getTimeValue().toString());
            map.put("endTime", endHourFlow.getTimeValue().toString());
        }
        return map;
    }

    //获取数据库最新的时间格式 开始时间 与 结束时间 - 水
    public Map getNewestWaterTime(String startDate, String endDate) {
        Map map = new HashMap();
        //获取当前时间
        WaterHourFlow startHourFlow = this.waterHourFlowService.getBaseMapper().selectOne(Wrappers.<WaterHourFlow>lambdaQuery()
                .like(WaterHourFlow::getTimeValue, startDate)
                .orderByAsc(WaterHourFlow::getTimeValue).last("LIMIT 1"));
        //获取上一条数据
        WaterHourFlow endHourFlow = this.waterHourFlowService.getBaseMapper().selectOne(Wrappers.<WaterHourFlow>lambdaQuery()
                .like(WaterHourFlow::getTimeValue, endDate)
                .orderByDesc(WaterHourFlow::getTimeValue).last("LIMIT 1"));
        if (ObjectUtils.isNotEmpty(startHourFlow) && ObjectUtils.isNotEmpty(endHourFlow)) {
            map.put("startTime", startHourFlow.getTimeValue().toString());
            map.put("endTime", endHourFlow.getTimeValue().toString());
        }
        return map;
    }
}